#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

#include "net.h"
#define BUFFER_SIZE 4096

int safe_realloc(void *ptr,size_t size){
    void *new_ptr=realloc(ptr,size);
    if (!new_ptr)
    {
        return -1;
    }
    ptr=new_ptr;    
    return 0;
}


//关闭fd读端
int fdsock_rdclose(int fd){
    return shutdown(fd,SHUT_RD);
}
//关闭fd写端
int fdsock_wrclose(int fd){
    return shutdown(fd,SHUT_WR);
}


/**
 * 解析字符串为 sockaddr（支持 UNIX 路径或 IP:Port）
 * @param addr_str 输入字符串（如 "/tmp/socket.sock" 或 "127.0.0.1:8080"）
 * @param addr     输出参数，填充 sockaddr_storage
 * @return 成功返回 0，失败返回 -1
 */
int parse_socket_address(const char *addr_str, struct sockaddr_storage *addr) {
    if (addr_str[0] == '/') {
        // UNIX 域套接字路径（如 "/tmp/socket.sock"）
        struct sockaddr_un *unix_addr = (struct sockaddr_un *)addr;
        unix_addr->sun_family = AF_UNIX;
        if (strlen(addr_str) >= sizeof(unix_addr->sun_path)) {
            fprintf(stderr,"UNIX socket path over 108 bytes limit too long: %s\n", addr_str);
            return -1;
        }
        strncpy(unix_addr->sun_path, addr_str, sizeof(unix_addr->sun_path) - 1);
        return 0;
    }else if (addr_str[0] == '[')
    {
        // IPv6
         // 尝试解析为 IP:Port（如 "[::1]:8080"）
         char *begin_bracket = strdup(addr_str);  // 复制字符串以便分割
         char *ip_str=begin_bracket + 1; //跳过'['
         char *close_bracket = strchr(ip_str, ']');
         if (!close_bracket || close_bracket[1]!=':') {
             free(begin_bracket);
             return -1;  // 无"]:"，格式错误
         }
        *close_bracket = '\0';    
        char *port_str = close_bracket + 2; // 跳过']:'
        int port = atoi(port_str);
        if (port <= 0 || port > 65535) {
            free(begin_bracket);
            return -1;  // 端口无效
        }
        //  解析IPv6
        struct sockaddr_in6 *tcp6_addr = (struct sockaddr_in6 *)addr;
        if (inet_pton(AF_INET6, ip_str, &tcp6_addr->sin6_addr) == 1) {
            tcp6_addr->sin6_family = AF_INET6;
            tcp6_addr->sin6_port = htons(port);
            free(begin_bracket);
            return 0;
        }
        free(begin_bracket);
        return -1;  // 不是有效的 IP 地址
    }else {
        // 尝试解析为 IP:Port（如 "127.0.0.1:8080"）
        char *ip_str = strdup(addr_str);  // 复制字符串以便分割
        char *port_str = strchr(ip_str, ':');
        if (!port_str) {
            free(ip_str);
            return -1;  // 无冒号，格式错误
        }
        *port_str = '\0';  // 分割 IP 和 Port
        port_str++;

        int port = atoi(port_str);
        if (port <= 0 || port > 65535) {
            free(ip_str);
            return -1;  // 端口无效
        }

        // 解析IPv4
        struct sockaddr_in *tcp_addr = (struct sockaddr_in *)addr;
        if (inet_pton(AF_INET, ip_str, &tcp_addr->sin_addr) == 1) {
            tcp_addr->sin_family = AF_INET;
            tcp_addr->sin_port = htons(port);
            free(ip_str);
            return 0;
        }
        free(ip_str);
        return -1;  // 不是有效的 IP 地址
    }
}

// 示例：打印 sockaddr 信息
void print_socket_address(const struct sockaddr_storage *addr) {
    char ip_str[INET6_ADDRSTRLEN];
    int port;

    switch (addr->ss_family) {
        case AF_UNIX: {
            struct sockaddr_un *unix_addr = (struct sockaddr_un *)addr;
            printf("UNIX Domain Socket: %s\n", unix_addr->sun_path);
            break;
        }
        case AF_INET: {
            struct sockaddr_in *tcp_addr = (struct sockaddr_in *)addr;
            inet_ntop(AF_INET, &tcp_addr->sin_addr, ip_str, sizeof(ip_str));
            port = ntohs(tcp_addr->sin_port);
            printf("TCP/IPv4: %s:%d\n", ip_str, port);
            break;
        }
        case AF_INET6: {
            struct sockaddr_in6 *tcp6_addr = (struct sockaddr_in6 *)addr;
            inet_ntop(AF_INET6, &tcp6_addr->sin6_addr, ip_str, sizeof(ip_str));
            port = ntohs(tcp6_addr->sin6_port);
            printf("TCP/IPv6: [%s]:%d\n", ip_str, port);
            break;
        }
        default:
            printf("Unknown address family\n");
    }
}

int exmple() {
    const char *examples[] = {
        "/tmp/server.sock",  // UNIX 域套接字
        "127.0.0.1:8080",    // IPv4
        "[::1]:8080",        // IPv6（带方括号）
        "0.0.0.0:80",        // IPv4 所有接口
        "invalid-address"    // 错误示例
    };

    for (int i = 0; i < sizeof(examples) / sizeof(examples[0]); i++) {
        struct sockaddr_storage addr;
        if (parse_socket_address(examples[i], &addr) == 0) {
            printf("Success: ");
            print_socket_address(&addr);
        } else {
            printf("Failed to parse: %s\n", examples[i]);
        }
    }

    return 0;
}



/**
 * 监听socket(支持 UNIX 路径或 IP:Port)
 * @param addr_str      输入字符串:（如 "/tmp/socket.sock" 或 "0.0.0.0:80"）
 * @param type      输入参数:（如 SOCK_STREAM）
 * @param listen_queue      输入参数： socket连接数
 * @return 成功返回 fd，失败返回 -1
 * @note 调用 socket、bind、listen 系统调用
 */
// int listenFrom(const char* addr_str,int type,int listen_queue)
// {
//     struct sockaddr_storage addr={0};
//     //解析地址
//     if (parse_socket_address(addr_str,&addr)<0)
//     {
//         printf("Failed to parse: %s\n", addr_str);
//         return -1;
//     }
//     print_socket_address(&addr);
//     //创建套接字
//     int server_socket;
//     server_socket = socket(addr.ss_family, type, 0);
//     if (server_socket<0)
//     {
//         printf("socket creating error: %s\n",strerror(errno));
//         return -1;
//     }

    
//     switch (addr.ss_family)  //绑定套接字
//     {
//     case AF_UNIX:
//         bind(server_socket,(struct sockaddr_un *)(&addr), 110u);
//         break;
//     case AF_INET:
//         bind(server_socket,(struct sockaddr_in *)(&addr), 16u);
//         break;
//     case AF_INET6:
//         bind(server_socket,(struct sockaddr_in6 *)(&addr), 28u);
//         break;
//     default:
//         fprintf(stderr,"Unsupported address family\n");
//         return -1;
//     }

//     //监听套接字,接收队列的长度5，在Server程序调用accept函数之前最大允许进入的连接请求数，多余的连接请求将被拒绝，典型取值为5
//     if (listen(server_socket,listen_queue)<0)
//     {
//         printf("Listen error: %s\n",strerror(errno));
//         return -1;
//     }
//     return server_socket;
// }

/*
 * 判断是否是 Unix socket
 * @param fd 输入文件描述符
 * @return 是 Unix socket 返回 1，否则返回 0
*/
int is_unix_socket(int fd) {
    int domain;
    socklen_t len = sizeof(domain);
#ifdef SO_DOMAIN
    if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &domain, &len) == -1) {
        perror("getsockopt failed");
        return -1; // 出错
    }
    return (domain == AF_UNIX); // 是 Unix socket 返回 1，否则返回 0
#else
        // 旧系统，不支持 SO_DOMAIN，只能判断是否是 AF_UNIX
        struct sockaddr_storage addr;
        socklen_t addr_len = sizeof(addr);
        if (getsockname(fd, (struct sockaddr *)&addr, &addr_len) == -1) {
            perror("getsockname failed");
            return -1; // 出错
        }
        return (addr.ss_family == AF_UNIX); // 是 Unix socket 返回 1，否则返回 0
#endif  
}

/**
 * 安全版监听服务（支持跨协议复用 + 智能错误恢复）
 * @param addr_str      地址字符串（格式详见 parse_socket_address_opt）
 * @param sock_type     socket类型 (SOCK_STREAM/SOCK_DGRAM)
 * @param backlog       最大挂起连接数（自动适配系统上限）
 * @return              成功返回非负文件描述符，失败返回 -1 并设置 errno
 * 
 * @note 自动清除残留UNIX socket文件，支持端口即时重用(SO_REUSEPORT)
 */
int listen_from(const char *addr_str, int sock_type, int backlog) {
    struct sockaddr_storage addr = {0};
    int sock_fd = -1;
    int ret = -1;

    // [1] 参数校验防御性编程
    if (!addr_str || !*addr_str) {
        errno = EINVAL;
        fprintf(stderr,"Invalid address string\n");
        goto cleanup;
    }

    // [2] 智能地址解析（启用详细错误日志）
    if (parse_socket_address(addr_str,&addr)<0)
    {
        fprintf(stderr,"Failed to parse: %s\n", addr_str);
        goto cleanup;
    }
    // [3] 协议族自动适配（AF_LOCAL优先处理）
    const int family = addr.ss_family;
    sock_fd = socket(family, sock_type, 0);
    if (sock_fd < 0) {
        fprintf(stderr,"socket() failed for %s: %s\n", addr_str, strerror(errno));
        goto cleanup;
    }
    // [4] 高级套接字选项设置
    const int reuse = 1;
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) {
        fprintf(stderr,"setsockopt(SO_REUSEADDR) failed for %s: %s\n", addr_str, strerror(errno));
    }
#ifdef SO_REUSEPORT
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int)) < 0) {
        fprintf(stderr,"setsockopt(SO_REUSEPORT) failed for %s: %s\n", addr_str, strerror(errno));
    }
#endif
    // [5] 预绑定处理（UNIX域需清理历史文件）
    if (family == AF_UNIX) {
        struct sockaddr_un *un = (struct sockaddr_un *)&addr;
        if (unlink(un->sun_path) < 0 && errno != ENOENT) {
            fprintf(stderr,"unlink() failed for %s: %s\n", un->sun_path, strerror(errno));
            goto cleanup;
        }
    }
    // [6] 通用绑定逻辑（自动计算地址结构长度）
    socklen_t addr_len = 0;
    switch (family) {
        case AF_UNIX:  addr_len = sizeof(struct sockaddr_un);  break;
        case AF_INET:  addr_len = sizeof(struct sockaddr_in);  break;
        case AF_INET6: addr_len = sizeof(struct sockaddr_in6); break;
        default:
            fprintf(stderr,"Unsupported address family: %d\n", family);
            errno = EAFNOSUPPORT;
            goto cleanup;
    }
    if (bind(sock_fd, (struct sockaddr *)&addr, addr_len) < 0) {
        fprintf(stderr,"bind() failed for %s: %s\n", addr_str, strerror(errno));
        goto cleanup;
    }

    // [7] 智能监听队列调整（适配系统上限）
    if (backlog <= 0) backlog = SOMAXCONN;
    if (listen(sock_fd, backlog) < 0) {
        fprintf(stderr,"listen() failed for %s: %s\n", addr_str, strerror(errno));
        goto cleanup;
    }
#ifdef DEBUG
    fprintf(stdout,"[server]: listen in %s\n",addr_str);
#endif

    // [8] UNIX域文件权限设置（防止未授权访问）
    if (family == AF_UNIX) {
        struct sockaddr_un *un = (struct sockaddr_un *)&addr;
        if (chmod(un->sun_path, 0666) < 0) {
            fprintf(stderr,"chmod() failed for %s: %s\n", un->sun_path, strerror(errno));
        }
    }

    ret = sock_fd; // 转移socket所有权
    sock_fd = -1;  // 阻止cleanup关闭

cleanup:
    if (sock_fd >= 0) close(sock_fd);
    return ret;
}


/**
 * 连接socket(支持 UNIX 路径或 IP:Port)
 * @param addr_str      输入字符串（如 "/tmp/socket.sock" 或 "0.0.0.0:80"）
 * @param type      输入参数 （SOCK_STREAM）
 * @return 成功返回 fd，失败返回 -1
 * @note 调用 connect 系统调用
 */
int connectTo(const char *addr_str,int type)
{
    struct sockaddr_storage addr={0};
    if (parse_socket_address(addr_str,&addr)<0)
    {
        fprintf(stderr, "[NET] Address parse failed: %s\n", addr_str);
        return -1;
    }
    int connect_socket;
    connect_socket = socket(addr.ss_family, type, 0);
    if (connect_socket<0)
    {
        fprintf(stderr, "[NET] Socket creating error: %s\n",strerror(errno));
        return -1;
    }
    socklen_t addr_len;
    switch (addr.ss_family)
    {
    case AF_UNIX:
        addr_len=110u;
        break;
    case AF_INET:
        addr_len=16u;
        break;
    case AF_INET6:
        addr_len=28u;
        break;
    default:
        addr_len=28u;
        break;
    }
    if (connect(connect_socket, (struct sockaddr*)&addr, addr_len) < 0)
    {
        printf("connect error: %s\n",strerror(errno));
        return -1;
    }
    return connect_socket;
}

/**
 * @brief 建立指定类型的网络连接（支持UNIX域/IPv4/IPv6）
 * @param endpoint 连接端点格式：
 *                - UNIX域:   /path/to/socket.sock
 *                - IPv4:     192.168.1.10:8080
 *                - IPv6:     [2001:db8::1]:8080
 * @param sock_type 套接字类型 SOCK_STREAM/SOCK_DGRAM
 * @return 成功返回连接描述符，失败返回-1并设置errno
 * @note 自动识别地址类型，支持TCP/UDP协议
 */
int connect_to(const char *addr_str, int sock_type, int timeout_sec) 
{
    struct sockaddr_storage addr = {0};
    //

    // 地址解析阶段
    if (parse_socket_address(addr_str, &addr) < 0) {
        fprintf(stderr, "[NET] Address parse failed: %s\n", addr_str);
        return -1;
    }

    // 协议类型推导
    int protocol = 0;
    if (sock_type == SOCK_STREAM) {
        protocol = IPPROTO_TCP;
    } else if (sock_type == SOCK_DGRAM) {
        protocol = IPPROTO_UDP;
    }

    // 套接字创建
    int sock = socket(addr.ss_family, sock_type, protocol);
    if (sock < 0) {
        perror("[NET] Socket creation failed");
        return -1;
    }

    // 连接超时配置（3秒）
    if (timeout_sec > 0) {
        struct timespec ts = { .tv_sec = timeout_sec, .tv_nsec = 0 };
        
        
        // struct timeval tv = { .tv_sec = timeout_sec, .tv_usec = 0 };
        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &ts, sizeof(ts));
    }
    socklen_t addr_len;
    switch (addr.ss_family)
    {
    case AF_UNIX:
        addr_len=110u;
        break;
    case AF_INET:
        addr_len=16u;
        break;
    case AF_INET6:
        addr_len=28u;
        break;
    default:
        addr_len=28u;
        break;
    }
    // 连接执行
    if (connect(sock, (struct sockaddr*)&addr, addr_len) < 0) {
        close(sock); // 连接失败立即释放资源
        perror("[NET] Connection failed");
        return -1;
    }

    // TCP_NODELAY优化
    if (sock_type == SOCK_STREAM && addr.ss_family != AF_UNIX) {
        int flag = 1;
        setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
    }

    return sock;
}


/**
 * @brief 通过 sendmsg 发送数据、文件描述符（fd）或两者
 * @param sockfd     目标套接字（必须为 AF_UNIX 类型）
 * @param fds        待发送的文件描述符（不需要发送 fd 时设为 -1）
 * @param data       待发送的数据缓冲区（不需要发送数据时设为 NULL）
 * @param data_len   数据长度（data 为 NULL 时设为 0）
 * @return 成功返回发送的字节数，失败返回 -1
 * @note 调用 sendmsg 系统调用
 */
int send_multiple_fds(int sock_fd, const int *fds, int fd_count, const char *data,size_t data_len,int flag) {
    struct msghdr msg = {0};
    struct iovec iov[1];
    

    // 1. 设置普通数据（可选）
    if (data)
    {
        iov[0].iov_base = (void*)data;
        iov[0].iov_len = data_len;  // 包含 '\0' 
    }else{
        char buf='\0';
        iov[0].iov_base = &buf;
        iov[0].iov_len = 1;  // 至少包含一个字节数据
    }
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;

    // 2. 设置控制信息（用于传递多个 FD）
    if (fds)
    {
        char ctrl_buf[CMSG_SPACE(sizeof(int) * MAX_FDS)];  // 控制信息缓冲区
        msg.msg_control = ctrl_buf;
        msg.msg_controllen = CMSG_SPACE(sizeof(int) * fd_count);
        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fd_count);
        memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * fd_count);// 将多个 FD 写入控制信息
    }else{
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
    }
    
    // 3. 发送消息
    ssize_t ret;
    if ((ret=sendmsg(sock_fd, &msg, flag)) < 0) {
        perror("sendmsg failed");
        return ret;
    }

#ifdef DEBUG
    printf("Sent reason: [%s] %d FDs and data: \033[0;32m{%s}\033[0m \n",strerror(errno), fd_count,data);
#endif
    return ret;
}


/**
 * @brief 通过 recvmsg 接收数据、文件描述符（fd）或两者
 * @param sockfd     目标套接字（必须为 AF_UNIX 类型）
 * @param received_fds 待接收的文件描述符
 * @param out_data   待接收的数据缓冲区
 * @return 成功返回接收的字节数，失败返回 -1
 * @note 调用 recvmsg 系统调用
 */
int recv_multiple_fds(int sock_fd, int *received_fds, char *out_data,int flag) {
    struct msghdr msg = {0};
    struct iovec iov[1];
    char ctrl_buf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
    int fd_count = 0;

    // 1. 设置数据缓冲区
    iov[0].iov_base = out_data;
    iov[0].iov_len = BUFFER_SIZE;
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;

    // 2. 设置控制信息缓冲区
    msg.msg_control = ctrl_buf;
    msg.msg_controllen = sizeof(ctrl_buf);

    // 3. 接收消息
    ssize_t n = recvmsg(sock_fd, &msg, flag);
    if (n < 0) {
        perror("recvmsg failed");
        return -1;
    }else if (n == 0)
    {
        msg.msg_iov = NULL;
        msg.msg_iovlen = 0;
    }else{
        out_data[n] = '\0';
    }
    
    // 4. 提取多个 FD
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
#ifdef DEBUG
    printf("Fds received num: %p\n",cmsg);
#endif
    if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
        fd_count = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
        memcpy(received_fds, CMSG_DATA(cmsg), sizeof(int) * fd_count);
#ifdef DEBUG
        printf("Received %d FDs:\n", fd_count);

        for (int i = 0; i < fd_count; i++) {
            printf("  FD %d: %d\n", i, received_fds[i]);
        }
#endif
    } else {
#ifdef DEBUG
        fprintf(stderr, "No FDs received\n");
#endif
    }
#ifdef DEBUG
    printf("Received data: \033[0;32m{%s}\033[0m \n",out_data);
#endif
    return n;
}


//转发fd
int fdproxy(int src_sock,int dst_sock){
    int proxyfd[1];
    char buf[1024];
    int ret=recv_multiple_fds(src_sock,proxyfd,buf,0);
    if (ret==-1)
    {
        return -1;
    }
    
    ret=send_multiple_fds(dst_sock,proxyfd,1,buf,ret,0);
    if (ret==-1)
    {
        return -1;
    }
    return 0;
}

int fd_handle(char *sockpath,char *msg){
    int client_fd=connectTo(sockpath,SOCK_STREAM);
    // 向服务器注册remote_fd
    int sock_peer[2];
    if (socketpair(AF_UNIX,SOCK_STREAM,0,sock_peer)==0)
    {
        // 客户注册remote_fd
        int fds[]={sock_peer[1]};
        printf("fd: %d\n",fds[0]);
        ssize_t ret = send_multiple_fds(client_fd,fds,sizeof(fds)/sizeof(int),msg,strlen(msg)+1,0);
        if (ret>=0)
        {
            // close(sock_peer[1]);
            close(client_fd);
            return sock_peer[0];
        }else{
            close(sock_peer[1]);
            close(client_fd);
            fprintf(stderr,"handle_fd error: %s\n",strerror(errno));
            fflush(stderr);
            return -1;
        }
    }
    close(client_fd);
    return -1;
}

int inotify(const char *path,void *info,size_t n){
    int client_fd=connectTo(path,SOCK_STREAM|SOCK_NONBLOCK);
    if (client_fd<0)
    {
        return -1;
    }
    int ret=send(client_fd,info,n,SOCK_NONBLOCK);
    close(client_fd);
    return ret;  
}

/**
 * @brief 发送多个数据块（可选文件描述符）
 * @param sock_fd    目标套接字（必须为 AF_UNIX 类型）
 * @param fds_info   待发送的文件描述符数组（fds[0]为文件描述符数量,不需要发送 fd 时设为NULL）
 * @param iov        待发送的数据块数组
 * @param iov_len    数据块数量
 * @return 成功返回发送的字节数，失败返回 -1
*/
int send_multi_fds(int sock_fd, const int *fds_info, struct Iovec *iov,int iov_len,int flag) {
    struct msghdr msg = {0};
    // 1. 设置普通数据
    msg.msg_iov = (struct iovec *)iov;
    msg.msg_iovlen = iov_len;
    
    // 2. 设置控制信息（用于传递多个 FD）
    if (fds_info)
    {
        char ctrl_buf[CMSG_SPACE(sizeof(int) * MAX_FDS)];  // 控制信息缓冲区
        msg.msg_control = ctrl_buf;
        msg.msg_controllen = CMSG_SPACE(sizeof(int) * (*fds_info));
        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        cmsg->cmsg_len = CMSG_LEN(sizeof(int) * (*fds_info));
        memcpy(CMSG_DATA(cmsg), fds_info+1, sizeof(int) * (*fds_info));// 将多个 FD 写入控制信息
    }else{
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
    }
    // 3. 发送消息
    ssize_t ret;
    if ((ret=sendmsg(sock_fd, &msg, flag)) < 0) {
        perror("sendmsg failed");
        return ret;
    }
#ifdef DEBUG
    if (fds_info)
    {
        printf("Sent reason: [%s] %d FDs and data: \033[0;32m{",strerror(errno), *fds_info);
        for (size_t i = 0; i < iov_len; i++)
        {
            printf("%s",(char*)iov[i].iov_base);
        }
        printf("}\033[0m\n");
    }
    else
    {
        printf("Sent reason: [%s] data:\033[0;32m{",strerror(errno));
        for (size_t i = 0; i < iov_len; i++)
        {
            printf("%s",(char*)iov[i].iov_base);
        }
        printf("}\033[0m\n");
    }
#endif
    return ret;
}

/**
 * @brief 接收多个数据块（可选文件描述符）
 * @param sock_fd     目标套接字（必须为 AF_UNIX 类型）
 * @param received_fds 待接收的文件描述符数组（received_fds[0]为文件描述符数量,不需要接收 recevied_fds 时设为NULL）
 * @param iov        待接收的数据块数组
 * @param iov_len    数据块数量
 * @return 成功返回接收的字节数，失败返回 -1
 */
int recv_multi_fds(int sock_fd, int *received_fds, struct Iovec *iov,int iov_len,int flag) {
    struct msghdr msg = {0};
    
    char ctrl_buf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
    int fd_count = 0;
    
    // 1. 设置数据缓冲区
    msg.msg_iov = (struct iovec *)iov;
    msg.msg_iovlen = iov_len;

    // 2. 设置控制信息缓冲区
    if (received_fds)
    {
        msg.msg_control = ctrl_buf;
        msg.msg_controllen = sizeof(ctrl_buf);
    }else{
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
    }

    // 3. 接收消息
    ssize_t n = recvmsg(sock_fd, &msg, flag);
    if (n < 0) {
        perror("recvmsg failed");
        return n;
    }else if (n == 0)
    {
        msg.msg_iov = NULL;
        msg.msg_iovlen = 0;
    }
    // 4. 提取多个 FD
    if (received_fds)
    {
        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
#ifdef DEBUG
        printf("Fds received num: %p\n",cmsg);
#endif
        if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
            fd_count = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
            memcpy(received_fds, CMSG_DATA(cmsg), sizeof(int) * fd_count);
#ifdef DEBUG
            printf("Received %d FDs:\n", fd_count);

            for (int i = 0; i < fd_count; i++) {
                printf("  FD %d: %d\n", i, received_fds[i]);
            }
#endif
        } else {
#ifdef DEBUG
            fprintf(stderr, "No FDs received\n");
#endif
        }
    }
#ifdef DEBUG
    printf("Received data:");
    for (size_t i = 0; i < iov_len; i++)
    {
        printf("\033[0;32m{%s}\033[0m",(char*)iov[i].iov_base);
    }
    printf("\n");
    // printf("Received data: \033[0;32m{%s}\033[0m \n",out_data);
#endif
    return n;
}



/************************http protocol*************************/

// 序列化http请求
int serialize_http_request_v1(const HTTP_REQUEST *req,char *request,int maxlen){
    int len = sprintf(
        request, 
        "%s %s %s\r\n%s\r\n%s",
        req->method,
        req->url,
        req->version,
        req->headers,
        req->body
    );
    return len;
}

// 解序列化http请求
int unserialize_http_request_v1( const char *request,HTTP_REQUEST *req){
    // 解析请求行
    char *headers=strstr(request,"\r\n");
    if (!headers || headers==request)
    {
        fprintf(stderr,"unserialize_http_request error: %s\n",request);
        fflush(stderr);
        return -1;
    }
    sscanf(request,"%s %s %s\r\n",req->method,req->url,req->version);
    // 解析请求头
    headers+=2;
    char *body=strstr(headers,"\r\n\r\n");
    if (body)
    {
        int headerlen=body-headers;
        strncpy(req->headers,headers,headerlen);
        req->headers[headerlen]='\0';
        strncpy(req->body,body+4,strlen(body)-4);
        req->body[strlen(body)-4]='\0';
    }else{
        size_t header_size=strlen(req->headers);
        strncpy(req->headers,headers,header_size);
        req->headers[header_size]='\0';
    }
    return 0;
}

// 序列化http响应
int serialize_http_response_v1(const HTTP_RESPONSE *res,char *response,int maxlen){
    // 构造响应行
    
    int len=snprintf(response,maxlen,"%s %d %s\r\n%s\r\n%s\r\n",res->version,res->status_code,res->status_msg,res->headers,res->body);
    return len;
}

// 解序列化http响应
int unserialize_http_response_v1( const char *response,HTTP_RESPONSE *res){
    // 解析响应行
    char *headers=strstr(response,"\r\n");
    if (!headers || headers==response)
    {
        fprintf(stderr,"unserialize_http_response error: %s\n",response);
        fflush(stderr);
        return -1;
    }
    sscanf(response,"%s %d %s\r\n",res->version,(int *)&res->status_code,res->status_msg);
    // 解析响应头
    headers+=2;
    char *body=strstr(headers,"\r\n\r\n");
    if (body)
    {
        int bodylen=body-headers;
        strncpy(res->headers,headers,bodylen);
        res->headers[bodylen]='\0';
        strncpy(res->body,body+4,strlen(body)-4);
        res->body[strlen(body)-4]='\0';
    }else{
        size_t header_size=sizeof(headers);
        strncpy(res->headers,headers,header_size);
        res->headers[header_size]='\0';
    }
    return 0;
}

// 发送http请求
int send_http_request_v1(int sockfd,const HTTP_REQUEST *req,const int *fds, int fd_count){
    if (fds && fd_count >0 && !is_unix_socket(sockfd)) return -1;
    char request[4096];
    serialize_http_request_v1(req,request,sizeof(request));
    return send_multiple_fds(sockfd,fds,fd_count,request,strlen(request),0); 
}

// 接收http请求
int recv_http_request_v1(int sockfd,HTTP_REQUEST *req,int *received_fds){
    char request[4096];
    struct Iovec request_iov[5];
    request_iov[0].iov_base = request;
    request_iov[0].iov_len = 4095;
    int len=recv_multi_fds(sockfd,received_fds,request_iov,1,0);
    // int len=recv_multiple_fds(sockfd,received_fds,request,0);
    if (len<=0)
    {
        return -1;
    }
    unserialize_http_request_v1(request,req);
    return 0;
}

// 发送http响应
int send_http_response_v1(int sockfd,const HTTP_RESPONSE *res,const int *fds, int fd_count){
    if (fds && fd_count >0 && !is_unix_socket(sockfd)) return -1;
    char response[4096];
    serialize_http_response_v1(res,response,sizeof(response));
    struct Iovec response_iov[3];
    response_iov[0].iov_base = response;
    response_iov[0].iov_len = strlen(response)+1;
    return send_multi_fds(sockfd,fds,response_iov,1,0);
    // return send_multiple_fds(sockfd,fds,fd_count,response,strlen(response),0);
}

// 接收http响应
int recv_http_response_v1(int sockfd,HTTP_RESPONSE *res,int *received_fds){
    char response[4096];
    int len=recv_multiple_fds(sockfd,received_fds,response,0);
    if (len<=0)
    {
        return -1;
    }
    unserialize_http_response_v1(response,res);
    return 0;
}

